﻿Imports System.Data

Public Class LocalUniverse

    Public Property Data As DataSet

    Public Sub Reset()

    End Sub

    Public Function GetMainTable() As DataTable

    End Function

    Public Function GetMainTable(ByVal name As String) As DataTable

    End Function

    Public Function GetParamTable(ByVal name As String) As DataTable

    End Function

    Public Function GetParamRelation(ByVal name As String) As DataRelation
        Dim t = New TableWrapper()
        Dim filter = t.Columns("WEIGHT") > 75.0

        t.Select(filter)

    End Function


End Class

Public Class TableWrapper

    Sub New()

    End Sub
    Sub New(ByVal view As DataView)

    End Sub

    Public Property View As DataView
    Public Property Columns As IDictionary(Of String, ColumnWrapper)

    Function [Select](ByVal expr As AdoExpression) As TableWrapper
        Return New TableWrapper(New DataView(View.Table, expr.ToString(), "", DataViewRowState.None))
    End Function

End Class

Public MustInherit Class AdoExpression

    Protected MustOverride Function Visit() As String
    Public MustOverride ReadOnly Property ExpectedType As Type

    
    Public Shared Widening Operator CType(ByVal col As DataColumn) As AdoExpression

    End Operator
    Public Shared Widening Operator CType(ByVal value As String) As AdoExpression
        Return New Constant(Of String)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As Single) As AdoExpression
        Return New Constant(Of Single)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As Integer) As AdoExpression
        Return New Constant(Of Integer)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As Double) As AdoExpression
        Return New Constant(Of Double)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As Long) As AdoExpression
        Return New Constant(Of Long)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As Boolean) As AdoExpression
        Return New Constant(Of Boolean)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As DateTime) As AdoExpression
        Return New Constant(Of DateTime)(value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As TimeSpan) As AdoExpression
        Return New Constant(Of TimeSpan)(value)
    End Operator

    Public Shared Operator +(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "+", False)
    End Operator
    Public Shared Operator -(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "-", False)
    End Operator
    Public Shared Operator *(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "*", False)
    End Operator
    Public Shared Operator /(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "/", False)
    End Operator

    Public Shared Operator <(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "<", True)
    End Operator
    Public Shared Operator >(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, ">", True)
    End Operator
    Public Shared Operator <=(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "<=", True)
    End Operator
    Public Shared Operator >=(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, ">=", True)
    End Operator

    Public Shared Operator =(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "=", True)
    End Operator
    Public Shared Operator <>(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "<>", True)
    End Operator
    Public Shared Operator Or(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "Or", True)
    End Operator
    Public Shared Operator And(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "And", True)
    End Operator

    Public Shared Operator Mod(ByVal left As AdoExpression, ByVal right As AdoExpression) As AdoExpression
        Return New Binary(left, right, "%", False)
    End Operator

    Public Shared Function Count(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("Count", value)
    End Function
    Public Shared Function Sum(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("Sum", value)
    End Function
    Public Shared Function Mean(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("Mean", value)
    End Function
    Public Shared Function Max(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("Max", value)
    End Function
    Public Shared Function Min(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("Min", value)
    End Function
    Public Shared Function StDev(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("StDev", value)
    End Function
    Public Shared Function Var(ByVal value As AdoExpression) As AdoExpression
        Return New Aggregate("Var", value)
    End Function





    Private Class Constant(Of T)
        Inherits AdoExpression

        Private value As T

        Sub New(ByVal value As T)
            Me.value = value
        End Sub
        Public Overrides ReadOnly Property ExpectedType As System.Type
            Get
                Return GetType(T)
            End Get
        End Property
        Protected Overrides Function Visit() As String
            Return value.ToString()
        End Function
    End Class
    Private Class Aggregate
        Inherits AdoExpression

        Private Method As String
        Private Parameter As AdoExpression

        Sub New(ByVal p1 As String, ByVal value As AdoExpression)
            ' TODO: Complete member initialization 
            Method = p1
            Parameter = value
        End Sub

        Public Overrides ReadOnly Property ExpectedType As System.Type
            Get
                Return Parameter.ExpectedType
            End Get
        End Property
        Protected Overrides Function Visit() As String
            Return Method & "(" & Parameter.Visit() & ")"
        End Function

    End Class
    Private Class Binary
        Inherits AdoExpression

        Private Left As AdoExpression
        Private Right As AdoExpression
        Private Op As String
        Dim IsBoolean As Boolean

      
        Sub New(ByVal Left As AdoExpression, ByVal Right As AdoExpression, ByVal Op As String, Optional ByVal IsBoolean As Boolean = False)
            Me.Left = Left
            Me.Right = Right
            Me.Op = Op
            Me.IsBoolean = IsBoolean

        End Sub

        Public Overrides ReadOnly Property ExpectedType As System.Type
            Get
                If IsBoolean Then
                    Return GetType(Boolean)
                End If
                Return Left.ExpectedType
            End Get
        End Property

        Protected Overrides Function Visit() As String
            Return String.Format("({0} {1} {2})", Left.Visit(), Op, Right.Visit())
        End Function
    End Class

End Class

Public Class DynamicDataView
    Inherits Dynamic.DynamicObject

    Dim _View As DataView

    Sub New(ByVal view As DataView)
        Me._View = view
    End Sub

    Public Overrides Function TryGetIndex(ByVal binder As System.Dynamic.GetIndexBinder, ByVal indexes() As Object, ByRef result As Object) As Boolean
        Return MyBase.TryGetIndex(binder, indexes, result)
    End Function
    Public Overrides Function TrySetIndex(ByVal binder As System.Dynamic.SetIndexBinder, ByVal indexes() As Object, ByVal value As Object) As Boolean
        Return MyBase.TrySetIndex(binder, indexes, value)
    End Function
    Public Overrides Function TryGetMember(ByVal binder As System.Dynamic.GetMemberBinder, ByRef result As Object) As Boolean
        Return MyBase.TryGetMember(binder, result)
    End Function
    Public Overrides Function TrySetMember(ByVal binder As System.Dynamic.SetMemberBinder, ByVal value As Object) As Boolean
        Return MyBase.TrySetMember(binder, value)
    End Function
End Class

Public Class DynamicDataRowView
    Inherits Dynamic.DynamicObject

    Dim _Row As DataRowView


    Sub New(ByVal row As DataRowView)
        Me._Row = row
    End Sub

    Public Overrides Function TrySetMember(ByVal binder As System.Dynamic.SetMemberBinder, ByVal value As Object) As Boolean
        Return MyBase.TrySetMember(binder, value)
    End Function
    Public Overrides Function TryGetMember(ByVal binder As System.Dynamic.GetMemberBinder, ByRef result As Object) As Boolean
        Return MyBase.TryGetMember(binder, result)
    End Function
End Class

Public Class ColumnWrapper
    Inherits AdoExpression

    Public Overrides ReadOnly Property ExpectedType As System.Type
        Get

        End Get
    End Property

    Protected Overrides Function Visit() As String

    End Function
End Class